package com.room.search.service.sms.smsimpl;

import com.room.search.config.SmsConfig;
import com.room.search.domain.enumeration.SmsResponseCodeEnum;
import com.room.search.exception.BaseException;
import com.room.search.exception.CommonException;
import com.room.search.service.sms.ISmsService;
import com.room.search.util.SmsCodeUtil;
import com.room.search.util.SmsUtil;
import com.tencentcloudapi.sms.v20190711.models.SendStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * By   : ghd.bright
 * Time : 2022/1/10
 * Description: 发送短信服务
 */
@Service
public class ISmsServiceImpl implements ISmsService {

    private final Logger logger = LoggerFactory.getLogger(ISmsServiceImpl.class);

    @Autowired
    private SmsConfig smsConfig;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /** 腾讯云短信模板id-短信验证码 */
    @Value("${sms-config.templateIds.code}")
    private String templateIdCode;


    @Override

    public void sendSmsCode(String phone) {
        // redis缓存的键
        final String smsKey = SmsCodeUtil.createSmsCacheKey(smsConfig.getPhonePrefix(), phone, "room_user_sign");

        //下发手机号码，采用 e.164 标准，+[国家或地区码][手机号]  示例如：+8613711112222， 其中前面有一个+号 ，86为国家码，13711112222为手机号，最多不要超过200个手机号
        String[] phoneNumbers = {"+86" + phone};
        //模板参数: 若无模板参数，则设置为空（第一个参数为随机验证码，第二个参数为有效时间）
        final String smsRandomCode = SmsCodeUtil.createSmsRandomCode();
        String[] templateParams = {
            smsRandomCode
        };

        SendStatus[] sendStatuses = SmsUtil.sendSms(smsConfig, templateIdCode, templateParams, phoneNumbers);
        String resCode = sendStatuses[0].getCode();
        if (resCode.equals(SmsResponseCodeEnum.OK.getCode())) {
            // 返回ok，缓存
            redisUtil().set(smsKey, smsRandomCode, Long.parseLong(smsConfig.getExpireTime()), TimeUnit.MINUTES);
        } else {
            logger.error("【短信业务-发送失败】phone: {}，errMsg: {}", phone, sendStatuses[0].getMessage());
            throw new BaseException(SmsResponseCodeEnum.SMS_NOT_SEND);
        }
    }

    @Override
    public boolean verifyCode(String phone, String code) {
        // redis缓存的键
        final String smsKey = SmsCodeUtil.createSmsCacheKey(smsConfig.getPhonePrefix(), phone,
            "room_user_sign");
        // 如果key存在（存在并且未过期）
        if (Boolean.TRUE.equals(redisTemplate.hasKey(smsKey))) {
            String cacheCode = redisUtil().get(smsKey);
            if (code.equals(cacheCode)) {
                //验证码正确
                //删除验证码缓存
                redisTemplate.delete(smsKey);
                logger.info("【短信业务-微信公众号手机认证成功】phone：{}" , phone);
                return true;
            } else {
                //验证码不正确
                logger.error("【短信业务-微信公众号手机认证失败】验证码错误。phone：{}", phone);
                throw new CommonException("验证码不正确");
            }
        } else {
            logger.error("【短信业务-微信公众号手机认证失败】验证码失效。phone：{}", phone);
            throw new CommonException("验证码失效");
        }
    }


    private ValueOperations<String, String> redisUtil() {
        return redisTemplate.opsForValue();
    }


}
